package com.ww.learn.coroutine

import kotlinx.coroutines.*
import java.lang.Integer.parseInt
import java.lang.Runnable
import kotlinx.coroutines.async
import kotlin.system.measureTimeMillis

fun caseWhen(obj: Any?) {
    when (obj) {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9 -> println("${obj} ===> 0-9之间的数字")
        "hello" -> println("${obj} ===> 这个是字符串hello")
        is Char -> println("${obj} ===> 这是一个Char类型数据")
        else -> println("${obj} ===> 类似Java中的case-switch中的默认路径")
    }
}

fun switch(x: Int) {
    val s = "123"
    when (x) {
        -1, 0 -> print("x == -1 or x == 0")
        1 -> print("x == 1")
        2 -> print("x == 2")
        8 -> print("x is 8")
        parseInt(s) -> println("x is 123")
        else -> {
            print("x is neither 1 nor 2")
        }
    }
}

fun test01(x: Int) {
    val validNumbers = arrayOf(1, 2, 3)
    when (x) {
        in 1..10 -> print("x is in the range")
        in validNumbers -> print("x is valid")
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
}

fun fact(n: Int): Int {
    var result = 1
    when (n) {
        0, 1 -> result = 1
        else -> result = n * fact(n - 1)
    }
    return result
}

fun sumFact(n: Int): Int {
    var sum = 0
    for (i in 1..n) {
        sum += fact(i)
    }
    return sum
}

class Person(var name: String, var age: Int, var sex: String) {
    override fun toString(): String {
        return "Person(name='$name', age=$age, sex='$sex')"
    }
}

class Person1 {
    lateinit var name: String
    var age: Int = 0
    lateinit var sex: String
    override fun toString(): String {
        return "Person1(name='$name', age=$age, sex='$sex')"
    }
}

class Person2() {
    lateinit var name: String
    var age: Int = 0
    lateinit var sex: String

    constructor(name: String) : this() {
        this.name = name
    }

    constructor(name: String, age: Int) : this(name) {
        this.name = name
        this.age = age
    }

    constructor(name: String, age: Int, sex: String) : this(name, age) {
        this.name = name
        this.age = age
        this.sex = sex
    }

    override fun toString(): String {
        return "Person1(name='$name', age=$age, sex='$sex')"
    }
}

abstract class Shape {
    abstract var width: Double
    abstract var height: Double
    abstract var radius: Double
    abstract fun area(): Double

    open fun onClick() {
        println("I am Clicked!")
    }
}

class Rectangle(override var width: Double, override var height: Double, override var radius: Double) : Shape() {
    override fun area(): Double {
        return height * width
    }

    override fun onClick() {
        println("点一点")
    }
}

class Circle(override var width: Double, override var height: Double, override var radius: Double) : Shape() {
    override fun area(): Double {
        return 3.14 * radius * radius
    }
}

class Triangle(override var width: Double, override var height: Double, override var radius: Double) : Shape() {
    override fun area(): Double {
        return 1 / 2.0 * height * width
    }
}

// data 数据类
data class LoginUser(val username: String, val password: String)

class NestedClassesDemo {
    class Outer {
        private val zero: Int = 0
        val one: Int = 1

        class Nested {
            fun getTwo() = 2
            class Nested1 {
                val three = 3
                fun getFour() = 4
            }
        }
    }
}

class NestedClassesDemo2 {
    class AnonymousInnerClassDemo {
        var isRunning = false
        fun doRun() {
            Thread(object : Runnable {
                override fun run() {
                    isRunning = true
                    println("doRun: i am running, isRunning = $isRunning")
                }
            }).start()
        }
    }
}

fun testWithFun() {
    // 普通写法
    val list = mutableListOf<String>()
    list.add("A")
    list.add("B")
    list.add("C")
    println("常规写法list = $list")

    // 使用with()函数写法
    with(ArrayList<String>()) {
        add("A")
        add("B")
        add("C")
        println("使用with函数写法this = $this")
    }.let { println(it) }
}

fun String.firstChar(): String {
    if (this.isEmpty()) {
        return ""
    }
    return this[0].toString()
}

fun String.lastChar(): String {
    if (this.isEmpty()) {
        return ""
    }
    return this[this.length - 1].toString()
}

fun <T> List<T>.filter(predicate: (T) -> Boolean): MutableList<T> {
    val result = ArrayList<T>()
    this.forEach {
        if (predicate(it)) {
            result.add(it)
        }
    }
    return result
}

open class Food
open class Fruit: Food()
class Apple: Fruit()
class Banana: Fruit()
class Grape: Fruit()

object GenericTypeDemo {
    fun addFruit(fruit: MutableList<Fruit>) {}
    fun getFruit(fruit: MutableList<Fruit>) {}
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L)
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L)
    return 29
}

fun printWithThreadInfo() {
    println("thread id: ${Thread.currentThread().id}, thread name: ${Thread.currentThread().name} --->")
}

fun printWithThreadInfo(param: String) {
    println("thread id: ${Thread.currentThread().id}, thread name: ${Thread.currentThread().name} ---> ${param}")
}

fun main() = runBlocking {
    val time = measureTimeMillis {
        val a = async(Dispatchers.IO) {
            printWithThreadInfo()
            delay(1000) // 模拟耗时操作
            1
        }
        val b = async(Dispatchers.IO) {
            printWithThreadInfo()
            delay(2000) // 模拟耗时操作
            2
        }
//        a.start()
//        b.start()
        printWithThreadInfo("${a.await() + b.await()}")
        printWithThreadInfo("end")
    }
    printWithThreadInfo("time: $time")
}





























